package com.llh.workflow;

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import weaver.general.BaseBean;
import weaver.general.TimeUtil;
import weaver.general.Util;
import weaver.system.SystemComInfo;

import java.util.HashMap;
import java.util.Map;

/**
 * @author 刘立华
 * @version 1.0.0
 * @ClassName CreateRequestUtil.java
 * @Description 此案例为鉴权和调用流程创建接口的案例。
 * @createTime 2021年06月22日 08:42:00
 */
public class CreateRequestUtil {
    private BaseBean logger = new BaseBean();
    //泛微OA提供APPID
    private final String APPID = Util.null2String(logger.getPropValue("wn_rest_workflow", "APPID"),
            "EEAA5436-7577-4BE0-8C6C-89E9D88805EA");

    public static void main(String[] args) {
        CreateRequestUtil util = new CreateRequestUtil();
        util.createWorkflowExample();
    }

    /**
     * 这是一个创建流程接口调用的例子
     */
    public void createWorkflowExample() {
        ///////////流程主表信息集合//////////////////
        JSONArray mainData = new JSONArray();
        //编号  单行文本赋值
        JSONObject bhObj = new JSONObject();
        bhObj.put("fieldName", "bh");
        // 字段值 OA人员id  3
        bhObj.put("fieldValue", System.currentTimeMillis() + "");
        mainData.add(bhObj);
        //识别号  单行文本赋值
        JSONObject sbhObj = new JSONObject();
        sbhObj.put("fieldName", "sbh");
        // 字段值 OA人员id  3
        sbhObj.put("fieldValue", System.currentTimeMillis() + "");
        mainData.add(sbhObj);

        JSONObject bbh = new JSONObject();
        bbh.put("fieldName", "bbh");
        // 字段值 OA人员id  3
        bbh.put("fieldValue", "V1");
        mainData.add(bbh);

        JSONObject sqrObj = new JSONObject();
        //字段名  申请人  浏览按钮
        sqrObj.put("fieldName", "sqr");
        // 字段值 OA人员id  5
        sqrObj.put("fieldValue", "1");
        mainData.add(sqrObj);


        //////明细表1的操作/////////////
        JSONArray workflowRequestTableRecords = new JSONArray();

        for (int i = 1; i < 6; i++) {

            //顾客方 单行文本
            JSONObject gkf = new JSONObject();
            gkf.put("fieldName", "gkf");
            gkf.put("fieldValue", "单行文本第" + i + "行");
            //订单发布时间 日期
            JSONObject ddfbsj = new JSONObject();
            ddfbsj.put("fieldName", "ddfbsj");
            ddfbsj.put("fieldValue", TimeUtil.getCurrentDateString());
            //零部件号 单行文本
            JSONObject lbjh = new JSONObject();
            lbjh.put("fieldName", "lbjh");
            lbjh.put("fieldValue", "011");
            //零部件名称  单行文本
            JSONObject lbjmc = new JSONObject();
            lbjmc.put("fieldName", "lbjmc");
            lbjmc.put("fieldValue", "螺母");
            //备注  单行文本
            JSONObject bz = new JSONObject();
            bz.put("fieldName", "bz");
            bz.put("fieldValue", "这是第" + i + "行的备注");
            JSONArray workflowRequestTableFields = new JSONArray();
            workflowRequestTableFields.add(gkf);
            workflowRequestTableFields.add(ddfbsj);
            workflowRequestTableFields.add(lbjh);
            workflowRequestTableFields.add(lbjmc);
            workflowRequestTableFields.add(bz);

            JSONObject object = new JSONObject();
            //recordOrder  新建时一定要写入0
            object.put("recordOrder", 0);
            object.put("workflowRequestTableFields", workflowRequestTableFields);
            workflowRequestTableRecords.add(object);
        }
        //明细表名
        String tableDBName = "formtable_main_2_dt1";
        JSONObject detailObj = new JSONObject();
        detailObj.put("workflowRequestTableRecords", workflowRequestTableRecords);
        detailObj.put("tableDBName", tableDBName);
        JSONArray detailData = new JSONArray();
        detailData.add(detailObj);

        JSONObject request = new JSONObject();
        JSONObject otherParams = new JSONObject();
        //新建流程是否默认提交到第二节点，可选值为[0 ：不流转 1：流转 (默认)]
        otherParams.put("isnextflow", 1);
        //delReqFlowFaild：新建流程失败是否默认删除流程，可选值为[0 ：不删除 1：删除 (默认)]
        otherParams.put("delReqFlowFaild", 1);
        // 不校验创建权限了   kb9.00.2011.00 以后支持
        otherParams.put("isVerifyPer", "0");
        logger.writeLog("detailData.toString() = " + detailData);
        request.put("requestName", "创建流程测试-" + TimeUtil.getCurrentTimeString());
        request.put("workflowId", 2);
        //mainData 一定要toString，否则接口收不到
        request.put("mainData", mainData.toJSONString());
        //detailData 一定要toStirng，否则接收不到
        request.put("detailData", detailData.toJSONString());
        request.put("otherParams", otherParams.toJSONString());
        logger.writeLog("流程创建接口入参: " + request);
        //调用创建流程接口
        String createRequest = rest_Create(request.toString(), "1");
        logger.writeLog("创建流程结果 = " + createRequest);
    }

    private Map<String, String> getTokenAndSpk(String address) {
        Map<String, String> mapResult = new HashMap<>();
        Map<String, Object> regist = regist(address);
        String spk = "";
        String token = "";
        if ((int) regist.get("code") == 0) {
            //系统公钥信息
            spk = (String) regist.get("spk");
            //秘钥信息
            String secret = (String) regist.get("secret");
            Map<String, Object> getoken = getoken(address, spk, secret);
            if ((int) getoken.get("code") == 0) {
                token = (String) getoken.get("token");
                logger.writeLog("获取到的token = " + token);
            } else {
                logger.writeLog("获取token失败原因：" + getoken.get("msg"));
            }
        } else {
            logger.writeLog("获取spk失败原因：" + regist.get("msg"));
        }
        mapResult.put("spk", spk);
        mapResult.put("token", token);
        return mapResult;
    }

    /**
     * 第一步：
     * 调用ecology注册接口,根据appid进行注册,将返回服务端公钥和Secret信息
     */
    private Map<String, Object> regist(String address) {
        //获取当前系统RSA加密的公钥
        RSA rsa = new RSA();
        String publicKey = rsa.getPublicKeyBase64();
        logger.writeLog("publicKey = " + publicKey);
        //调用ECOLOGY系统接口进行注册
        String data = HttpRequest.post(address + "/api/ec/dev/auth/regist")
                .header("appid", APPID)
                .header("cpk", publicKey)
                .timeout(2000)
                .execute().body();
        // 打印ECOLOGY响应信息
        // logger.writeLog("regist()：" + data);
        Map<String, Object> datas = JSONUtil.parseObj(data);
        return datas;
    }

    /**
     * 第二步：
     * <p>
     * 通过第一步中注册系统返回信息进行获取token信息
     */
    private Map<String, Object> getoken(String address, String spk, String secret) {
        // 公钥加密,所以RSA对象私钥为null
        RSA rsa = new RSA(null, spk);
        //对秘钥进行加密传输，防止篡改数据
        String encryptSecret = rsa.encryptBase64(secret, CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey);
        //调用ECOLOGY系统接口进行注册
        String data = HttpRequest.post(address + "/api/ec/dev/auth/applytoken")
                .header("appid", APPID)
                .header("secret", encryptSecret)
                .header("time", "5*1000")
                .execute().body();
        Map<String, Object> datas = JSONUtil.parseObj(data);
        return datas;
    }
    /**
     * 第三步：
     * post Form 调用ecology系统的rest接口，请求头部带上token和用户标识认证信息
     *
     * @param address ecology系统地址
     * @param params  请求参数Map
     *                注意：ECOLOGY系统所有POST接口调用请求头请设置 "Content-Type","application/x-www-form-urlencoded; charset=utf-8"
     */
    public String rest_Create(String params, String createrid) {
        SystemComInfo systemComInfo = new SystemComInfo();
        //需要配置系统地址
        String address = systemComInfo.getOaaddress();
        Map<String, String> tokenAndSpk = getTokenAndSpk(address);
        String token = tokenAndSpk.get("token");
        logger.writeLog("token = " + token);
        String spk = tokenAndSpk.get("spk");
        Map<String, Object> map = JSONUtil.parseObj(params);
        //封装请求头参数
        RSA rsa = new RSA(null, spk);
        //对用户信息进行加密传输,暂仅支持传输OA用户ID  1表示当前用户为系统管理员
        String encryptUserid = rsa.encryptBase64(createrid, CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey);
        logger.writeLog("encryptUserid = " + encryptUserid);
        //调用ECOLOGY系统接口
        String data = HttpRequest.post(address + "/api/workflow/paService/doCreateRequest")
                .header("appid", APPID)
                .header("token", token)
                .header("userid", encryptUserid)
                .header("Content-Type", "application/x-www-form-urlencoded;charset=utf-8")
                .form(map)
                .execute().body();
        return data;
    }
}
